package com.huawei.push.controller.service;

import com.alibaba.fastjson.JSONObject;
import com.huawei.push.controller.Json.ResultJson;
import com.huawei.push.controller.enity.VivoApplyTokenEnity;
import com.huawei.push.controller.enity.VivoPushListRequestEnity;
import com.huawei.push.controller.enity.VivoTaskRequestEnity;
import com.huawei.push.controller.vo.VivoPushListResponseVo;
import com.huawei.push.controller.vo.VivoSigleResponseVo;
import com.huawei.push.controller.vo.VivoTaskVo;
import com.huawei.push.controller.vo.VivoTokenResponseVo;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * Vivo手机推送通知栏消息
 */
@Component
public class VivoAppSendMsg {
    private static Log log = LogFactory.getLog(VivoAppSendMsg.class);

    //请求token的实体封装参数类
    @Resource
    VivoApplyTokenEnity vivoApplyTokenEnity;
    //请求VIVO的批量推送获取taskId的参数类

    //配置文件中 的token鉴权url信息
    @Value("${vivo.tokenUrl}")
    private String tokenUrl;
    //批量推送获取taskID的请求u'r'l
    @Value("${vivo.taskIdUrl}")
    private String taskIdUrl;
    //批量推送URL
    @Value("${vivo.pushUrl}")
    private String pushListUrl;

    @Value("${vivo.sigleUrl}")
    private String sigleUrl;

    /**
     * 请求http获取vivo的token
     * 限制一天一个appid只能由10000次请求
     * @return token字符串或NULL
     */
    public String getToken(){
        //  获取token及其他请求参数字符串
         String param =vivoApplyTokenEnity.getParamJson();
         if (StringUtils.hasLength(param)){
            // json格式提交URl请求信息
             String  tokenInfo=   postMethodByJson(tokenUrl,param,null);
             if (StringUtils.hasLength(tokenInfo)){
                 VivoTokenResponseVo vo = JSONObject.parseObject(tokenInfo, VivoTokenResponseVo.class);
                //   接口代码不是0的全部是失败
                 if (vo.getResult()==0){
                     log.info(vo.toString());
                     return vo.getAuthToken();
                 }
                 log.debug("vivo接口请求失败： ："+vo.toString());
             }
        }
        log.debug("http请求接口失败"+tokenUrl+"JSON:"+param);
        return null;
    }


    /**
     *  广播消息 及单推消息
     * 限制：默认根据客户端SDK订阅数自动配置
     * @param regIds 用户请求内容 id
     * @param token 获取的token
     * @param requestId 用户id
     * @param title 信息标题
     * @param content 信息内容
     * @return
     */
    public String sendMsg(List<String> regIds, String token,String requestId,String title ,String content){
         VivoTaskRequestEnity vivoTaskRequestEnity =new VivoTaskRequestEnity(title,content,requestId);
         if (!StringUtils.hasLength(token)){
             log.debug("token为空");
             return ResultJson.bad("vivo的token不能为空",null);
         }
        if (!check(vivoTaskRequestEnity.getTitle(),40)){
            log.debug("标题超出20个汉字长度");
            return ResultJson.bad("标题不要超出20个汉字长度且不能为空",null);
        }else if (!check(vivoTaskRequestEnity.getContent(),100)){
            log.debug("消息内容超出50个汉字长度");
            return ResultJson.bad("消息内容不要超出50个汉字长度且不能为空",null);

        }else if (!check(vivoTaskRequestEnity.getRequestId(),64)){
            log.debug("用户请求requestId为空！");
            return ResultJson.bad("用户请求requestId为空！",null);
        }

        try{
//            批量推送reid必须是大于等于2的
            if (regIds.size()>1){
                //获取taskid 请求taskURl
                log.debug("开始请求taskID url:"+taskIdUrl);
                log.debug("参数："+JSONObject.toJSON(vivoTaskRequestEnity).toString()+"token"+token);

                VivoTaskVo taskVo=JSONObject.parseObject(postMethodByJson(taskIdUrl,JSONObject.toJSONString(vivoTaskRequestEnity) ,token) ,VivoTaskVo.class);
                if (taskVo.getResult()==0){
//                获取任务ID
                    String taskId = taskVo.getTaskId();

                    if (StringUtils.hasLength(taskId)){
                        log.info("请求task成功"+taskId);
                        //批量推送接口
                        VivoPushListRequestEnity plist = new VivoPushListRequestEnity();
                        plist.setRegIds(regIds);
                        plist.setTaskId(taskId);
                        plist.setRequestId(requestId);
                        VivoPushListResponseVo pushVo=JSONObject.parseObject( postMethodByJson(pushListUrl,JSONObject.toJSONString(plist),token),VivoPushListResponseVo.class);

                        if (pushVo.getResult()==0){
                            log.info("批量请求成功");
                            return ResultJson.ok(pushVo.getDesc(),pushVo.getInvalidUsers());
                        }

                        return ResultJson.bad(pushVo.getDesc(),null);
                    }
                    log.debug("taskId为空！"+taskVo.toString());
                    return ResultJson.bad("taskId为空",null);
                }
                log.debug(taskVo.toString());
                return ResultJson.bad(taskVo.getDesc(),null);
            }else {
//                单推
                if (regIds != null && regIds.size() == 1) {
                    vivoTaskRequestEnity.setRegId(regIds.get(0));
                    VivoSigleResponseVo sigleVo = JSONObject.parseObject( postMethodByJson(sigleUrl, JSONObject.toJSONString(vivoTaskRequestEnity), token), VivoSigleResponseVo.class);
                    if (sigleVo.getResult() == 0) {
                        log.info("单推请求成功");
                        return ResultJson.ok(sigleVo.getDesc(), sigleVo.getInvalidUser());
                    }
                    return ResultJson.bad(sigleVo.getDesc(), null);
                }
            }
            return ResultJson.bad("regId不能为空",null);


        }catch (Exception e){
            e.printStackTrace();
            log.debug("发生异常"+e.getMessage());
            return ResultJson.bad("服务异常",null);
        }
     }

    /**
     * 校验非空及字符长度 按照一个汉字2字符的格式
     * @param str
     * @param len
     * @return
     */
    public boolean check(String str,int len){
         if (!StringUtils.hasLength(str)){
            return false;
        }
        return getWordCount(str) <= len;
    }
    /**
     * @param url     要访问的URL地址(http://www.xxx.com?)
     * @param urlParm 参数(id=1212&pwd=2332)
     * @return 结果字符串
     * @Title: postMethod
     * @Description: 根据URL跨域获取输出结果，支持https
     */
    public static String postMethodByForm(String url, String urlParm) {
        HttpClient httpClient = new HttpClient();

        if (null == url || "".equals(url)) {
            return null;
        }
        PostMethod post = new PostMethod(url); // new UTF8PostMethod(url);
        if (null != urlParm && !"".equals(urlParm)) {
            String[] arr = urlParm.split("&");
            NameValuePair[] data = new NameValuePair[arr.length];
            for (int i = 0; i < arr.length; i++) {
                String name = arr[i].substring(0, arr[i].lastIndexOf("="));
                String value = arr[i].substring(arr[i].lastIndexOf("=") + 1);
                data[i] = new NameValuePair(name, value);
            }
            post.setRequestBody(data);
        }
        int statusCode = 0;
        String pageContent = "";
        try {
            statusCode = httpClient.executeMethod(post);
            if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {

                pageContent = post.getResponseBodyAsString();
                return pageContent;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            post.releaseConnection();
        }
        return null;
    }

    /**
     * 功能同上但是 是以application/json方式提交
     * @param url
     * @param toJson
     * @return
     */
    public static String postMethodByJson(String url, String  toJson ,String token)  {
        HttpClient httpClient = new HttpClient();

        if (null == url || "".equals(url)) {
            return null;
        }
        PostMethod post = new PostMethod(url);

        int statusCode = 0;
        String pageContent = "";
        try {
            RequestEntity requestEntity = new StringRequestEntity(toJson ,"application/json" ,"UTF-8");

            post.setRequestEntity(requestEntity);
            post.setRequestHeader("Content-Type","application/json");
            if (StringUtils.hasLength(token)){
                post.setRequestHeader("authToken",token);
            }
            //默认的重试策略
            post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
            post.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);//设置超时时间

            statusCode = httpClient.executeMethod(post);
            if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
                pageContent = post.getResponseBodyAsString();
                return pageContent;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            post.releaseConnection();
        }
        return null;
    }

    /**
     * 转换中文字符长度
     * @param s
     * @return
     */
    public static int getWordCount(String s)
    {
        int length = 0;
        for(int i = 0; i < s.length(); i++)
        {
            int ascii = Character.codePointAt(s, i);
            if(ascii >= 0 && ascii <=255){
                length++;
            } else{
                length += 2;
            }
        }
        return length;

    }
}
